﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GoodMan.Infrastructure.Entities.Entity;
using GoodMan.Infrastructure.Entities;
using GoodMan.Infrastructure.Entities.Enum;
using GoodMan.Tool.Framework;
using System.Data.SqlClient;
using GoodMan.Tool.Configration;

namespace GoodMan.Portal.Biz
{
    public class OrderBiz
    {
        public static string OrderCodeGenerator(AreaCode areaCode)
        {
            return String.Format("{0}000{1}{2}", (int)areaCode,
                DateTime.Now.ToString("yyyyMMddHHmm"), new Random().Next(1, 1000).ToString().PadLeft(4, '0'));
        }
        /// <summary>
        /// [超级管理|学校管理员]查询订单列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Order> GetAllOrderList(int page, int takeSize)
        {
            var count = new Order().Count(c => true);
            using (Context ctx = new Context())
            {
                var data = (from c in ctx.Order
                            join d in ctx.Dormitory
                             on c.DormitoryID equals d.Id
                            orderby c.Id descending
                            select new { c, d.Name })
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c => new Order().Set(c.c).LoadDormitory(
                               new Dormitory() { Name = c.Name }))
                           .ToList();
                //var data = ctx.Order
                //           .OrderByDescending(c => c.OrderDate)
                //           .Skip(page * takeSize)
                //           .Take(takeSize)
                //           .ToList()
                //           .Select(c => new Order().Set(c))
                //           .ToList();
                var list = new ItemListBox<Order>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }
        public static decimal GetAllOrderPriceSum(string userName)
        {
            using (Context ctx = new Context())
            {
                var result = ctx.ExcuteSQL("select sum(TotalPrice) from T_Order where UserName = @username and status=@status",
                    new SqlParameter("username", userName),
                    new SqlParameter("Status", (int)OrderStatus.Completed));
                if (result.Rows.Count > 0 && !String.IsNullOrEmpty(result.Rows[0][0].ToString()))
                {
                    return Decimal.Parse(result.Rows[0][0].ToString());
                }
                return 0;
            }
        }
        /// <summary>
        /// [楼栋管理员]查询订单统计
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Order> GetOrderListForStaff(int domitoryid, int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var count = new Order().Count(c => c.DormitoryID == domitoryid);
                var data = ctx.Order
                           .Where(c => c.DormitoryID == domitoryid)
                           .OrderBy(c => c.Id)
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c => new Order().Set(c))
                           .ToList();
                var list = new ItemListBox<Order>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }

        /// <summary>
        /// [楼栋管理员]查询待处理订单
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Order> GetPendingOrderListForStaff(int domitoryid, int status, int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var count = new Order().Count(c => c.DormitoryID == domitoryid && c.Status == status);
                var data = ctx.Order
                           .Where(c => c.DormitoryID == domitoryid && c.Status == status)
                           .OrderBy(c => c.Id)
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c => new Order().Set(c))
                           .ToList();
                var list = new ItemListBox<Order>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }

        /// <summary>
        /// [校级财务人员]查询订单统计
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Order> GetOrderListForOfficer(int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var count = new Order().Count(c => c.Id > 0);
                var data = from c in ctx.Order
                           group c by c.HandleUser into g
                           select new
                           {
                               TotalPrice = g.Where(i => i.Status > 3).Sum(i => i.TotalPrice),
                               TotalNum = g.Count(i => i.Status > 3),
                               SuccessPrice = g.Where(i => i.Status == 4).Sum(i => i.TotalPrice),
                               SuccessNum = g.Count(i => i.Status == 4),
                               CancelPrice = g.Where(i => i.Status == 5).Sum(i => i.TotalPrice),
                               CancelNum = g.Count(i => i.Status == 5)
                           };
                // ToList()
                var list = new ItemListBox<Order>(); //new ItemListBox<Order>(data).BuildPage(
                //count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }

        /// <summary>
        /// [超级财务人员]查询订单统计
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Order> GetOrderListForFinanOfficer(int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var count = new Order().Count(c => c.Id > 0);
                var data = from c in ctx.Order
                           group c by c.HandleUser into g
                           select new
                           {
                               TotalPrice = g.Where(i => i.Status > 3).Sum(i => i.TotalPrice),
                               TotalNum = g.Count(i => i.Status > 3),
                               SuccessPrice = g.Where(i => i.Status == 4).Sum(i => i.TotalPrice),
                               SuccessNum = g.Count(i => i.Status == 4),
                               CancelPrice = g.Where(i => i.Status == 5).Sum(i => i.TotalPrice),
                               CancelNum = g.Count(i => i.Status == 5)
                           };
                // ToList()
                var list = new ItemListBox<Order>(); //new ItemListBox<Order>(data).BuildPage(
                //count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }


        /// <summary>
        /// [楼栋管理员]修改订单状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public static bool ModifyOrderStatus(int id, int status)
        {
            try
            {
                var order = new Order().Find(id.ToString());
                if (order != null)
                {
                    order.Status = (OrderStatus)status;
                    //标识处理者
                    order.HandleUser = System.Web.HttpContext.Current.User.Identity.Name;
                    var ord = order.PostModify();
                    if (ord != null)
                    {
                        if (order.Status == OrderStatus.Completed)
                        {
                            //更新库存
                            var orderdetail = new OrderDetail().FindAll(c => c.OrderId == id);
                            if (orderdetail != null && orderdetail.Any())
                            {
                                foreach (var detail in orderdetail)
                                {
                                    var repertory = new ProductRepertory().Find(c => c.ProductId == detail.ProductId && c.DormitoryId == order.DormitoryID);
                                    if (repertory != null)
                                    {
                                        repertory.Remain -= detail.Num;
                                        repertory.PostModify();
                                    }
                                }
                            }
                        }
                        if (ord.AreaCode == AreaCode.Integration && ord.Status != OrderStatus.Cancelled) {
                            //如果是积分商品，其状态不为取消则不用退还积分，否则退还该积分
                            return true;
                        }
                        if (ord.AreaCode == AreaCode.Integration && ord.Status == OrderStatus.Cancelled)
                        {
                            var integral = new Integration().FindByKey(order.UserName);
                            if (integral != null)
                            {
                                integral.CostValue += (int)(ord.TotalPrice * SiteResource.CostRank);
                                integral.PostModify();
                            }
                        }
                        else
                        {
                            bool bmain = MaintainIntegral(order.UserName, order.TotalPrice);
                        }
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch
            {
                return false;
            }
            return false;
        }

        /// <summary>
        /// [楼栋管理员]维护用户积分
        /// </summary>
        /// <param name="id"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public static bool MaintainIntegral(string username, decimal orderprice)
        {
            try
            {
                var integral = new Integration().FindByKey(username);
                if (integral == null)
                {
                    integral = new Integration()
                    {
                        Activity = 0,
                        Balance = 0,
                        CostValue = (int)Math.Round(orderprice, 0),
                        LockBalance = 0,
                        UserName = username
                    }.PostAdd();
                    return integral != null;
                }
                else
                {
                    integral.CostValue += (int)Math.Round(orderprice, 0);
                    return integral.PostModify() != null;
                }
            }
            catch(Exception e)
            {
                LogHelper.Write( CommonLogger.System, LogLevel.Error, e);
                return false;
            }
        }
        /// <summary>
        /// 积分处理
        /// </summary>
        /// <param name="username"></param>
        /// <param name="integrationCost"></param>
        /// <param name="IsPlus"></param>
        /// <returns></returns>
        public static bool DealIntegral(string username, int integrationCost, bool IsPlus)
        {
            try
            {
                var integral = new Integration().FindByKey(username);
                if (IsPlus)
                {
                    integral.CostValue += integrationCost;
                     
                }
                else
                {
                    integral.CostValue = integral.CostValue-integrationCost;
                    
                }
                integral.PostModify();
                 
            }
            catch (Exception e)
            {
                LogHelper.Write(CommonLogger.System, LogLevel.Error, e);
                return false;
            }
            return true;
        }

        /// <summary>
        /// [校级财务人员]修改退款状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public static bool ModifyRefundStatus(int id, int status)
        {
            try
            {
                var refund = new Refund().Find(id.ToString());
                if (refund != null)
                {
                    refund.Status = (RefundStatus)status;
                    return refund.PostModify() != null;
                }
            }
            catch
            {
                return false;
            }
            return false;
        }

        /// <summary>
        /// [超级管理|学校管理员|楼栋管理员]根据条件检索订单
        /// </summary>
        /// <param name="usrole">角色</param>
        /// <param name="domitoryid">楼栋ID</param>
        /// <param name="realName">真实姓名</param>
        /// <param name="dtstart">开始时间</param>
        /// <param name="dtend">结束时间</param>
        /// <param name="status">订单状态</param>
        /// <param name="isSelf">标识为自己，楼栋管理员可以查询自己处理的单子</param>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <param name="orderCount"></param>
        /// <param name="totalPrice"></param>
        /// <returns></returns>
        public static ItemListBox<Order> OrderQuery(UserRole usrole, int domitoryid, string realName, string dtstart, string dtend, int status,bool isSelf, int page, int takeSize,ref int orderCount,ref decimal totalPrice)
        {
            using (Context ctx = new Context())
            {
                var query = from c in ctx.Order
                            join d in ctx.Dormitory
                            on c.DormitoryID equals d.Id
                            join u in ctx.User
                            on c.UserName equals u.UserName
                            select new { c, d.Name,u.RealName };
                
                if (!string.IsNullOrEmpty(realName))
                {
                    query = query.Where(c => c.RealName.Contains(realName));
                }
                if (!string.IsNullOrEmpty(dtstart))
                {
                    DateTime dstart = Convert.ToDateTime(dtstart);
                    query = query.Where(c => c.c.OrderDate >= dstart);
                }
                if (!string.IsNullOrEmpty(dtend))
                {
                    DateTime dend = Convert.ToDateTime(dtend);
                    query = query.Where(c => c.c.OrderDate <= dend);
                }
                if (status > 0)
                {
                    query = query.Where(c => c.c.Status == status);
                }
                var count = 0;
                var list = new ItemListBox<Order>();
                if (usrole == UserRole.Admin || usrole == UserRole.CollegeAdmin)
                {
                    count = query.Count(c => c.c.Id > 0);
                    
                    #region 计算价格
                    List<Order> dataListTemp = query
                           .OrderByDescending(c => c.c.OrderDate)                           
                           .ToList()
                           .Select(c => new Order().Set(c.c))
                           .ToList();
                    totalPrice = ClacTotalPrice(dataListTemp);
                    #endregion
                    var data = query
                           .OrderByDescending(c => c.c.OrderDate)
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c => new Order().Set(c.c))
                           .ToList();
                    list = new ItemListBox<Order>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                }
                else if (usrole == UserRole.Staff)
                {
                    if (isSelf)
                        query = query.Where(c => c.c.HandleUser.Equals(System.Web.HttpContext.Current.User.Identity.Name));

                    count = query.Count(c => c.c.DormitoryID == domitoryid);
                    #region 计算价格
                    List<Order> dataListTemp = query.Where(c => c.c.DormitoryID == domitoryid)
                           .OrderByDescending(c => c.c.OrderDate)
                           .ToList()
                           .Select(c => new Order().Set(c.c))
                           .ToList();
                    totalPrice = ClacTotalPrice(dataListTemp);
                    #endregion
                    var data = query.Where(c => c.c.DormitoryID == domitoryid)
                           .OrderByDescending(c => c.c.OrderDate)
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c =>
                               {
                                   var order = new Order().Set(c.c);
                                   order.UserRealName = c.RealName;
                                   return order;
                               })
                           .ToList();
                    list = new ItemListBox<Order>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                }
                orderCount = count;//总订单数量
                return list;
            }
        }

        /// <summary>
        /// 计算订单的总价格
        /// </summary>
        /// <param name="orderList"></param>
        /// <returns></returns>
        private static decimal ClacTotalPrice(List<Order> orderList) 
        {
            decimal totalPrice = 0.00m;
            if (orderList != null && orderList.Count != 0)
            {
                foreach (var item in orderList)
                {
                    totalPrice += item.TotalPrice;
                }
            }
            return totalPrice;
        }
        /// <summary>
        /// 【学校财务人员】按条件查询订单
        /// </summary>
        /// <returns></returns>
        public static ItemListBox<Order> OrderQueryForOfficer(string staffname, string dtstart, string dtend, int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var query = from c in ctx.Order select c;
                if (!string.IsNullOrEmpty(staffname))
                {
                    query = query.Where(c => c.HandleUser == staffname);
                }
                if (!string.IsNullOrEmpty(dtstart))
                {
                    DateTime dtsat = Convert.ToDateTime(dtstart);
                    query = query.Where(c => System.Data.Objects.EntityFunctions.DiffDays(c.OrderDate, dtsat) >= 0);
                }
                if (!string.IsNullOrEmpty(dtend))
                {
                    DateTime dend = Convert.ToDateTime(dtend);
                    query = query.Where(c => System.Data.Objects.EntityFunctions.DiffDays(c.OrderDate, dend) <= 0);
                }

                var count = new Order().Count(c => c.Id > 0);
                var data = from c in query
                           group c by c.HandleUser into g
                           select new
                           {
                               TotalPrice = g.Where(i => i.Status > 3).Sum(i => i.TotalPrice),
                               TotalNum = g.Count(i => i.Status > 3),
                               SuccessPrice = g.Where(i => i.Status == 4).Sum(i => i.TotalPrice),
                               SuccessNum = g.Count(i => i.Status == 4),
                               CancelPrice = g.Where(i => i.Status == 5).Sum(i => i.TotalPrice),
                               CancelNum = g.Count(i => i.Status == 5)
                           };
                // ToList()
                var list = new ItemListBox<Order>(); //new ItemListBox<Order>(data).BuildPage(
                //count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }

        /// <summary>
        /// 【超级财务人员】按条件查询订单
        /// </summary>
        /// <returns></returns>
        public static ItemListBox<Order> OrderQueryForFinanOfficer(string dtstart, string dtend, int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var query = from c in ctx.Order select c;
                if (!string.IsNullOrEmpty(dtstart))
                {
                    DateTime dtsat = Convert.ToDateTime(dtstart);
                    query = query.Where(c => System.Data.Objects.EntityFunctions.DiffDays(c.OrderDate, dtsat) == 0);
                }
                if (!string.IsNullOrEmpty(dtend))
                {
                    DateTime dend = Convert.ToDateTime(dtend);
                    query = query.Where(c => System.Data.Objects.EntityFunctions.DiffDays(c.OrderDate, dend) == 0);
                }

                var count = new Order().Count(c => c.Id > 0);
                var data = from c in query
                           group c by c.HandleUser into g
                           select new
                           {
                               TotalPrice = g.Where(i => i.Status > 3).Sum(i => i.TotalPrice),
                               TotalNum = g.Count(i => i.Status > 3),
                               SuccessPrice = g.Where(i => i.Status == 4).Sum(i => i.TotalPrice),
                               SuccessNum = g.Count(i => i.Status == 4),
                               CancelPrice = g.Where(i => i.Status == 5).Sum(i => i.TotalPrice),
                               CancelNum = g.Count(i => i.Status == 5)
                           };
                // ToList()
                var list = new ItemListBox<Order>(); //new ItemListBox<Order>(data).BuildPage(
                //count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }


        /// <summary>
        /// 【学校财务人员】查询退款申请列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Refund> GetApplyRefundList(int status, int page, int takeSize)
        {
            var count = new Refund().Count(c => c.Status == status);
            using (Context ctx = new Context())
            {
                var data = ctx.Refund.Where(c => c.Status == status)
                           .OrderByDescending(c => c.Id)
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c => new Refund().Set(c))
                           .ToList();
                var list = new ItemListBox<Refund>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }

        /// <summary>
        /// 【学校财务人员】按条件查询退款申请列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<Refund> ApplyRefundQuery(string applyname, string domitory, string dtstart, string dtend, int status, int page, int takeSize)
        {
            using (Context ctx = new Context())
            {
                var query = from c in ctx.Refund select c;
                if (!string.IsNullOrEmpty(applyname))
                {
                    query = query.Where(c => c.ApplyUserName == applyname);
                }
                if (!string.IsNullOrEmpty(domitory))
                {
                    //query = query.Where(c => c);
                }
                if (!string.IsNullOrEmpty(dtstart))
                {
                    DateTime dstart = Convert.ToDateTime(dtstart);
                    query = query.Where(c => System.Data.Objects.EntityFunctions.DiffDays(c.ApplyDate, dstart) >= 0);
                }
                if (!string.IsNullOrEmpty(dtend))
                {
                    DateTime dend = Convert.ToDateTime(dtend);
                    query = query.Where(c => System.Data.Objects.EntityFunctions.DiffDays(c.ApplyDate, dend) <= 0);
                }

                var count = new Refund().Count(c => c.Status == status);
                var data = ctx.Refund.Where(c => c.Status == status)
                           .OrderByDescending(c => c.Id)
                           .Skip(page * takeSize)
                           .Take(takeSize)
                           .ToList()
                           .Select(c => new Refund().Set(c))
                           .ToList();
                var list = new ItemListBox<Refund>(data).BuildPage(
                    count, page, takeSize, new PageParameter() { Style = "workspace" });
                return list;
            }
        }

        public static bool ModifyOrderPayWay(int id, int payway)
        {
            try
            {
                var order = new Order().Find(id.ToString());
                if (order != null)
                {
                    order.Payway = (PayWay)payway;
                    return order.PostModify() != null;
                }
            }
            catch
            {
                return false;
            }
            return false;
        }

        public static ItemListBox<OrderDetail> GetSaleRecordByProductId(int productId = 0, int page = 0, int pageSize = 10)
        {
            int count = 0;
            using (Context ctx = new Context())
            {
                 count = (from c in ctx.OrderDetail
                            join d in ctx.Order
                            on c.OrderId equals d.Id
                          where c.ProductId == productId && (d.Status == (int)OrderStatus.Completed || d.Status == (int)OrderStatus.Paid
                          ||d.Status==(int)OrderStatus.WaitForDeliver)
                            select new { c, d }
                          ).Count();
            }
            
            using (Context ctx = new Context())
            {
                var data=(from c in ctx.OrderDetail
                          join d in ctx.Order
                          on c.OrderId equals d.Id
                          join e in ctx.User
                          on d.UserName equals e.UserName
                          where c.ProductId == productId && (d.Status == (int)OrderStatus.Completed || d.Status == (int)OrderStatus.Paid
                          || d.Status == (int)OrderStatus.WaitForDeliver)
                          orderby d.OrderDate descending
                          select new { c, d, e }
                          ).Skip(page * pageSize)
                           .Take(pageSize)
                           .ToList()
                           .Select(f => new OrderDetail().Set(f.c)
                               .LoadOrder(f.d).LoadUser(f.e))
                           .ToList();
                var list = new ItemListBox<OrderDetail>(data).BuildPage(
                   count, page, pageSize, new PageParameter() { Style = "home" });

                return list;
            
            }
           
        }

        public static Order SaveOrder(Order order, List<OrderDetail> orderDetailList,OrderHistory orderhistory)
        {
             
            var orderTemp = order.PostAdd();
            foreach (var orderDetail in orderDetailList)
            {
                 
                orderDetail.OrderId = orderTemp.Id;
                orderDetail.PostAdd();
            }
            orderhistory.OrderId = orderTemp.Id;
            orderhistory.PostAdd();
            return orderTemp;
        }

        public static int GetProductSaleCount(int productId = 0)
        {
            var orderdtailList=new OrderDetail().FindAll(c => c.ProductId == productId);
            if(orderdtailList!=null)
            {
                return orderdtailList.Sum(c => c.Num);
            }
            return 0;
           
        }

        public static bool IsHasAppraise(int productId)
        {
            if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
            {
                var username = System.Web.HttpContext.Current.User.Identity.Name;

                int buycount = 0;
                using (Context ctx = new Context())
                {
                    buycount = (from c in ctx.OrderDetail
                                join d in ctx.Order
                                on c.OrderId equals d.Id
                                where c.ProductId == productId && d.UserName == username &&d.Status==(int)OrderStatus.Completed
                                select new { c, d })
                              .ToList()
                              .Count;
                }
                if (buycount <= 0)
                {
                    return false;
                }
                else
                {
                    var appcount = new Appraise().Count(c => c.ProductId == productId && c.UserName == username);
                    if (appcount < buycount)
                    {
                        return true;
                    }
                }
                
            }
            return false;
        }

        public static List<Order> GetNewOrders(string userName, int page, int pageSize)
        {
            using (Context ctx = new Context())
            {
                var order = new Order().FindAll(
                    c => c.UserName == userName, c => c.Id, page, pageSize);
                return order;
            }
        }

        public static bool IsViewAppraisie(int id)
        {
            var products = ProductBiz.ProductAppraisie(id);
            bool flag = false;
            if (products != null && products.Count > 0)
            {
                flag = true;
            }
            return flag;
        }
    }
}
